
// Using an interrupt to generate a tone. 
// Eric McCreath 2012  - GPLv3

// To compile and install:
//   avr-gcc -DF_CPU=16000000UL -mmcu=atmega328p -o interrupt.out interrupt.c
//   avr-objcopy -O ihex -R .eeprom interrupt.out interrupt.hex
//   avrdude -b57600 -patmega328p -cstk500v1 -P/dev/ttyUSB0 -U flash:w:interrupt.hex


#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>


void SetupThreadSwapTimer()
{   
	TCCR2A = (1<<WGM21); // clear timer on compare match
	TCCR2B = (1<<CS22);  // timer uses main system clock with 1/8 prescale
	OCR2A  = 0xFF; 
	TIMSK2 = (1<<OCIE2A); // call interrupt on output compare match
}


/*
int main() {
	SetUpTimer();
	sei( );    // Enable interrupts
	method1();
	return 0;
} 

sp1h, sp1l, sp2h, sp2l;
uint8_t currentThread = 0;
uint8_t numThreads = 2;
uint8_t stackPointers[4];
uint8_t firstSwitch = 1;

ISR(TIMER2_COMPA_vect,ISR_NAKED)

 {
    reti();
	asm("push r0");
	asm("push r1");
	asm("push r2");
	asm("push r3");
	// ...
	stackPointers[2*currentThread] = SPH;
	stackPointers[2*currentThread + 1] = SPL;
	currentThread = (currentThread + 1) % numThreads;
	if (firstSwitch)
	{
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		asm("push r0");
		firstSwitch = 0;
		sei( );
		method2();
		// Call new funtion
	}
	else
	{
		SPH = stackPointers[2*currentThread];
		SPL = stackPointers[2*currentThread + 1];
		// ...
		asm("pop r3");
		asm("pop r2");
		asm("pop r1");
		asm("pop r0");
	}
	sei( );
 }
 */
 /*
SIGNAL(TIMER2_COMPA_vect)
{
   if (PORTB & 1<<PB1) {
      PORTB &= ~(1<<PB1);   // set pin 15 low
   } else {
      PORTB |= 1<<PB1;   // set pin 15 high
   }
}
*/
